package tp.pr5.mv.window;

import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;

import tp.pr5.mv.CPU;
import tp.pr5.mv.Controller;
import tp.pr5.mv.Instruction;
import tp.pr5.mv.Memory;
import tp.pr5.mv.Observable;
import tp.pr5.mv.OperandStack;
import tp.pr5.mv.ProgramCounter;
import tp.pr5.mv.ProgramMV;

@SuppressWarnings("serial")
public class TPMVWindow extends JFrame implements CPU.Observer {
	
	/* La ventana de la máquina virtual está compuesta de una botonera (con botones run, step y stop),
	 * un ProgramPanel (muestra la lista de instrucciones del programa) y un panel con los componentes
	 * relativos a la entrada y a la salida de la maquina virtual (EntradaSalidaMaquina)
	 * */
	
	private ProgramPanel programPanel;
	private Botonera botonera;
	private EntradaSalidaMaquina entradaSalida;
	private BarraEstado barraEstado;
	
	
	public TPMVWindow(Controller c, Observable<CPU.Observer> observableCPU, Observable<OperandStack.Observer> observableStack, Observable<Memory.Observer> observableMem) {
		
		super( "Máquina Virtual de TP");
		setSize(800,600);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		
		setLayout(new BorderLayout() );
		
		programPanel = new ProgramPanel();
		add(programPanel, BorderLayout.WEST);
		
		
		entradaSalida = new EntradaSalidaMaquina(c, observableCPU, observableStack, observableMem );
	    add(entradaSalida, BorderLayout.CENTER);
		
		
		botonera = new Botonera(c);
		add(botonera, BorderLayout.NORTH);
		
		barraEstado = new BarraEstado();
		add(barraEstado, BorderLayout.SOUTH);
				
		observableCPU.addObserver(this);
		
		observableCPU.addObserver(programPanel);
		
		observableCPU.addObserver(botonera);
		
		observableCPU.addObserver(barraEstado);
		observableStack.addObserver(barraEstado);
		observableMem.addObserver(barraEstado);
		
	}
	
	// Metodos que devuelven JTextArea con los cuadros de texto de entrada y salida 
	
	public JTextArea getTextoSalida() {
		return entradaSalida.getTextoSalida();
	}

	public JTextArea getTextoEntrada() {
		return entradaSalida.getTextoEntrada();
	}

	@Override
	public void onStartInstrExecution(Instruction ins) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onEndInstrExecution(Instruction instr, Memory mem,
			OperandStack stack, ProgramCounter pc) {}

	@Override
	public void onHalt() {}

	@Override
	public void onReset(ProgramMV program){}

	@Override
	public void onStartRun() {}

	@Override
	public void onEndRun(boolean aborted) {}

	@Override
	public void onTrap(Instruction instr, String trapMessage) { // Muestra un cuadro de dialogo si se ha producido una excepción
		JOptionPane.showMessageDialog(null, trapMessage);
		
	}

	
}
